#pragma once
#include <iostream>
#include <list>
#include <exception>
#include <string.h>
#include "thread.hpp"
#include "mutex.hpp"
#include "sem.hpp"
#include "cond.hpp"
#include "task(test).hpp"
#include "log.hpp"
#define THREAD_NUM 5
#define MAX_TASK_NUM 100000

template <class Task>
class threadpool
{
    // 中间函数,用于线程传参
    static void *work(void *args)
    {
        threadpool *th_pool = static_cast<threadpool<Task> *>(args);
        th_pool->run();
        return args;
    }

public:
    threadpool(int thread_num = THREAD_NUM, int max_task_num = MAX_TASK_NUM);

    // 向队列添加任务
    bool append(Task task);

    // 线程执行本体
    bool run();

    ~threadpool();

private:
    // 线程数量
    int _thread_num;

    // 创建线程数组, 大小为thread_num
    thread *_thr_array;

    // 信号量-----是否有任务处理
    sem _semaphore;

    // 互斥锁-----保护任务队列,保证线程互斥
    mutex _mtx;

    // 最多派发的任务数量
    int _max_task_num;

    // 任务队列
    std::list<Task> _t_queue;

    // 判断线程是否停止
    bool _stop;
};
template <class Task>
threadpool<Task>::threadpool(int thread_num, int max_task_num) : _thread_num(thread_num), _thr_array(nullptr), _max_task_num(max_task_num), _stop(false)
{
    if (_thread_num <= 0 || _max_task_num <= 0)
    {
        log_message(ERROR,"线程or任务队列数量无效");
        throw std::exception();
    }

    _thr_array = new thread[_thread_num];
    if (!_thr_array)
        throw std::exception();

    for (int i = 0; i < _thread_num; ++i)
    {
        _thr_array[i].push(work, this);
        // 创建线程
        if (0 != _thr_array[i].create())
        {
            throw std::exception();
            log_message(ERROR, "创建线程失败");
            std::cerr << errno << std::endl;
        }
        log_message(NORMAL,"创建线程成功");
        // 线程分离
        if (0 != _thr_array[i].detach())
        {
            log_message(ERROR,"线程分离出错");
            throw std::exception();
            std::cerr << errno << std::endl;
        }
        log_message(NORMAL,"线程分离成功");
    }
}

// 向队列添加任务
template <class Task>
bool threadpool<Task>::append(Task task)
{
    _mtx.lock();
    if (_t_queue.size() >= _max_task_num)
    {
        _mtx.unlock();
        return false;
    }
    _t_queue.push_back(task);
    _mtx.unlock();
    _semaphore.post();
    log_message(NORMAL,"添加任务成功");
    return true;
}

// 线程执行本体
template <class Task>
bool threadpool<Task>::run()
{
    while (!_stop)
    {
        _semaphore.wait();
        _mtx.lock();
        if (_t_queue.empty())
        {
            _mtx.unlock();
            continue;
        }
        Task task = _t_queue.front();
        _t_queue.pop_front();
        _mtx.unlock();
        // 执行内部函数
        std::cout << "执行结果" << task.solution() << std::endl;
        log_message(NORMAL,"执行任务成功");
    }
}
template <class Task>
threadpool<Task>::~threadpool()
{
    delete[] _thr_array;
    _stop = true;
}